﻿/*
 * @author: wizardc
 */

using Dou.Clip;
using Dou.Job;
using Unity.Burst;
using Unity.Mathematics;
using UnityEngine;

namespace Demo.WorldMap
{
    /// <summary>
    /// 场景静态数据相机控制器
    /// </summary>
    public class SceneStaticCameraCtl : MonoBehaviour
    {
        /// <summary>
        /// 关联的摄像机
        /// </summary>
        public Camera camera;
        
        /// <summary>
        /// 当前相机的唯一ID
        /// </summary>
        public string name;
        
        private Vector3 _lastPos = Vector3.one * float.MinValue;
        private Quaternion _lastRotate;
        
        private FrustumClipping _clipping = new FrustumClipping();
        
        void OnEnable()
        {
            SceneStaticRendererMgr.instance.AddCameraCtl(this);
        }

        void Update()
        {
            var needUpdate = GetNeedUpdate();
            if (needUpdate)
            {
                _clipping.Update(camera);
            }
        }

        private bool GetNeedUpdate()
        {
            var pos = camera.transform.position;
            var rot = camera.transform.rotation;
            if (!Mathf.Approximately((pos - _lastPos).sqrMagnitude, 0))
            {
                _lastPos = pos;
                _lastRotate = rot;
                return true;
            }
            if (!Mathf.Approximately(Quaternion.Angle(rot, _lastRotate), 0))
            {
                _lastRotate = rot;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取裁剪类型
        /// </summary>
        public FrustumClippingType GetClipping(ref Bounds bounds)
        {
            return _clipping.GetClipping(ref bounds);
        }
        
        /// <summary>
        /// 获取裁剪类型
        /// </summary>
        public FrustumClippingType GetClipping(float3 center, float3 extents)
        {
            return _clipping.GetClipping(center, extents);
        }
        
        /// <summary>
        /// 获取裁剪类型
        /// </summary>
        [BurstCompile]
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public unsafe FrustumClippingType GetClipping(float* ptr)
        {
            float3 center = new float3(*(ptr + 12), *(ptr + 13), *(ptr + 14));
            float3 extents = new float3(*(ptr + 3), *(ptr + 7), *(ptr + 3));
            return _clipping.GetClipping(center, extents);
        }
        
        void OnDisable()
        {
            SceneStaticRendererMgr.instance.RemoveCameraCtl(this);
        }
    }
}
